package cn.ustb.controller;

import cn.ustb.entity.*;
import cn.ustb.service.StudentBasicInfoService;
import cn.ustb.service.StudentGradeService;
import cn.ustb.serviceImpl.StudentBasicInfoServiceImpl;
import cn.ustb.serviceImpl.StudentGradeServiceImpl;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.lang.reflect.Method;
import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * 学生成绩servlet
 * 1.教务员查询学生成绩
 * 2.获取学生成绩后统计分析：计算总分，平均分，绩点等等
 * 3.学生用户查询自己的成绩
 *
 * @author yuyan
 */
@WebServlet("*.grade")
public class CourseGradeServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doPost(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //1.获取ServletPath：/addUser.do
        String servletPath = request.getServletPath();
        //2.去除 / 和 .do ，得到类似于addUser这样的字符串
        String methodName = servletPath.substring(1, servletPath.length() - 6);

        try {
            //3.利用反射获取methodName对应的方法
            Method method = getClass().getDeclaredMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
            //4.利用反射调用对应的方法
            method.invoke(this, request, response);
        } catch (Exception e) {
            e.printStackTrace();
        }


    }

    /**成绩统计分析：比如计算绩点,绩点排名等等**/
    @SuppressWarnings("unused")
    private void gradeAnalysis(HttpServletRequest request, HttpServletResponse response)
            throws IOException {
        HttpSession session = request.getSession();
        String yearTerm = request.getParameter("yearTerm");
        //获取要查询的所有学生的信息，放进List中
        List<StudentBasicInformation> students = getStudent(request);

        //获取每一位学生与其对应的所有的成绩，作为键值对存入map中
        Map<StudentBasicInformation,List<StudentGrade>> map = getAllGradeMap(students, yearTerm);
        //获取每一位学生的成绩统计分析结果
        Map<StudentBasicInformation, GradeAnalysisResult> results = getAnalysisResult(map);
        //将每一位学生的成绩分析结果放入session中
        session.setAttribute("results", results);
        //重定向到jsp显示页面
        response.sendRedirect(request.getContextPath() + "/gradeAnalysis.jsp");
    }

    /**获取成绩分析结果，把结果放入一个数组中**/
    private Map<StudentBasicInformation, GradeAnalysisResult> getAnalysisResult(
            Map<StudentBasicInformation, List<StudentGrade>> map) {
        //List results = new ArrayList();
        Map<StudentBasicInformation, GradeAnalysisResult> GradeMap = new HashMap<>();

        for(Map.Entry<StudentBasicInformation,List<StudentGrade>> entry : map.entrySet()){
            StudentBasicInformation stu = entry.getKey();
            List<StudentGrade> studentGrades = entry.getValue();
            //获取课程门数
            int courseCount = studentGrades.size();
            if(courseCount != 0){
                //获取总分
                int score = getScore(studentGrades);
                //平均分
                double averScore = score / courseCount;
                //平均学分绩点
                double gradePoint = getGradePoint(studentGrades);
                //平均学分成绩
                double averCreditGrade = (gradePoint + 5) * 10;
                //使平均分、平均学分绩点、平均学分成绩输出两位小数（四舍五入）
                DecimalFormat df = new DecimalFormat("#.00");

                GradeAnalysisResult gradeAnalysisResult = new GradeAnalysisResult(stu.getStudentId(),
                        courseCount, score, df.format(gradePoint), df.format(averCreditGrade), df.format(averScore));

                GradeMap.put(stu, gradeAnalysisResult);
            }
        }

        return GradeMap;
    }

    /**求平均学分绩点**/
    private double getGradePoint(List<StudentGrade> studentGrades) {
        StudentGrade studentGrade;
        double credit = 0.0,sum = 0.0;

        for (StudentGrade grade : studentGrades) {
            studentGrade = grade;
            sum = sum + Double.parseDouble(studentGrade.getGradePoint()) * Double.parseDouble(studentGrade.getCredit());
            credit = credit + Double.parseDouble(studentGrade.getCredit());

        }

        return sum / credit;
    }

    private int getScore(List<StudentGrade> studentGrades) {
        int score = 0;

        Iterator<StudentGrade> iter = studentGrades.iterator();
        StudentGrade studentGrade;
        while(iter.hasNext()){
            studentGrade= iter.next();
            score = score + Integer.parseInt(studentGrade.getScore());
        }
        return score;
    }

    /**教务员查询学生成绩**/
    @SuppressWarnings("unused")
    private void deanQuery(HttpServletRequest request, HttpServletResponse response)
            throws IOException {
        HttpSession session = request.getSession();
        String yearTerm = request.getParameter("yearTerm");

        List<StudentBasicInformation> students = getStudent(request);


        Map<StudentBasicInformation,List<StudentGrade>> map = getAllGradeMap(students, yearTerm);

        session.setAttribute("map", map);

        response.sendRedirect(request.getContextPath() + "/gradeQuery.jsp");
    }



    private Map<StudentBasicInformation, List<StudentGrade>> getAllGradeMap(
            List<StudentBasicInformation> students, String yearTerm) {
        Map<StudentBasicInformation,List<StudentGrade>> map = new HashMap<>();
        StudentGradeService studentGradeService=new StudentGradeServiceImpl();

        for(StudentBasicInformation sbi : students){
            List<StudentGrade> studentGrades = studentGradeService.getAllWithYearTerm(sbi.getStudentId(),yearTerm);
            map.put(sbi, studentGrades);
        }
        return map;
    }

    /**获取条件查询到的所有学生信息**/
    private List<StudentBasicInformation> getStudent(
            HttpServletRequest request){
        String academy = request.getParameter("academy");
        String profession = request.getParameter("profession");
        String className = request.getParameter("className");
        String studentId = request.getParameter("studentId");
        String studentName = request.getParameter("studentName");

        CriterStudent cs = new CriterStudent(academy, profession, className, studentName, studentId);
        StudentBasicInfoService studentBasicInfoService=new StudentBasicInfoServiceImpl();

        return studentBasicInfoService.getForListWithCriterStudent(cs);
    }

    /**学生用户查询自己的成绩**/
    @SuppressWarnings("unused")
    private void studentQuery(HttpServletRequest request, HttpServletResponse response)
            throws IOException {
        HttpSession session = request.getSession();

        User user = (User) session.getAttribute("user");

        StudentGradeService studentGradeService=new StudentGradeServiceImpl();
        List<StudentGrade> studentGradesBiXiu = studentGradeService.getBiXiucourseGradeList(user);
        List<StudentGrade> studentGradesXuanXiu = studentGradeService.getXuanXiucourseGradeList(user);


        session.setAttribute("studentGradesBiXiu", studentGradesBiXiu);
        session.setAttribute("studentGradesXuanXiu", studentGradesXuanXiu);


        response.sendRedirect(request.getContextPath() + "/courseGrade.jsp");
    }




}
